prompt.bash

#!/usr/bin/env bash


## 
# Just an idea to keep around in case I want to polish it. (heck it might already be good to go)
# function prompt_vim(){
#     local -n answer="$1"
#     file="$(mktemp ${codeDir}/tmp/vim_input.XXX)"
#
#     vim -u "${codeDir}/vimrc" "$file"
#     answer=$(<$file)
#     rm "$file"
# }

## 
# @arg prompt message
# @arg promptAnswerVar
function prompt(){
    # @TODO Integrate exiting by default so you'd just write `prompt "msg" arg || return` 
		# & Take a flag to disable printing of exit status
	# @TODO fix output... When going to line 2, it just wraps back to the first line, clearing the prompt message

    question="$(msg -n "${cCommand}${1}${cOff}")"
    msg -n "$question"
    if [[ -n "$prompt_answer" ]];then
        local -n output_answer=${2}
        output_answer="$prompt_answer"
        echo ":  ${prompt_answer}"
        prompt_answer=""
        return
    else
        read -e -p ":" ${2}
    fi
}


# Prompts a user & checks if user aborted the prompt
# Usage: prompt_or_quit "A MESSAGE" usersAnswer -e || return
# By default an empty message means QUIT=true
# -e is optional & indicates EMPTY message means QUIT=false
# where QUIT is the return value
function prompt_or_quit(){
    local -n OUTPUT=$2
    question="$(msg -n "${cCommand}${1}${cOff}${cInstruct} (q-quit)${cOff}")"
    msg -n "$question"
    read -e -p ":" OUTPUT
    if [[ "$3" == "-e" && -z "$OUTPUT" ]];then
        return 0
    fi
    is_quit_str "$OUTPUT" \
        || return 0;
    return 1
}

# Prompts a user for input & uses default if they do not provide input
# Usage: prompt_or_default "Your Question" "default_answer" usersAnswer
# Has no return value
function prompt_or_default(){
    local -n OUTPUT=$3
    question="$(msg -n "${cCommand}${1}${cOff}${cInstruct} defaults to [${2}]${cOff}")"
    msg -n "$question"
    read -e -p "" OUTPUT
    msg
    if [[ -z "$OUTPUT" ]];then
        OUTPUT="$2"
    fi
}

##
# prompt for yes or no
# return 0 (true) if yes
# return 1 (false) if no
#
# @example prompt_yes_or_no "Do you like it?" || return ## to return when answer is 'no'
# @example prompt_yes_or_no "Do you like it?" boolArgName ## to set $boolArgName to true/false (0/empty)
#
function prompt_yes_or_no(){
    # arg2 is optional  
    if [[ -n "$2" ]];then
        local -n BOOL_ANSWER=$2
    fi
    question="$(msg -n "${cCommand}${1}${cOff}${cInstruct} (y/no)${cOff}")"
    msg -n "$question"
    read -e -p ":" ANSWER
    if [[ "$ANSWER" == "y" || "$ANSWER" == "Y" || "$ANSWER" == "yes" ]];then
        BOOL_ANSWER=0
        return 0;
    elif [[ "$ANSWER" == "n" || "$ANSWER" == "no" || "$ANSWER" == "N" || "$ANSWER" == "NO" || "$ANSWER" == "No" ]];then
        BOOL_ANSWER=
        return 1;
    else
        # msg_status ""
        BOOL_ANSWER=
        return 1;
    fi
}

prompt_enter(){
    local answer;
    prompt "$1 ${cInstruct}[enter] to continue" response
    if [[ $response == "" ]]; then
        return 0;
    fi
    return 1;
}

## 
# Choose an answer from a passed array
# @extra Name your array `array_to_choose_from`
# @arg answer var name to store the user's answer in
# Set `prompt_choose_from_array_multi=1` prior to calling to select multiple items
#
# @usage local -n array_to_choose_from=my_array; prompt_choose_from_array answerVarName
     
function prompt_choose_from_array(){
### This seems to have a comprehensive sorting function
## https://stackoverflow.com/questions/7442417/how-to-sort-an-array-in-bash
### But I'm not going to integrate that now.

    menu=("# Choose one")
    # menu+=("'${cInstruct}${relDir}${cOff}")

    local -n arrayAnswer="${1}"

    for item in "${array_to_choose_from[@]}";do
        # name="$(basename "$file")"
        menu+=("$item" "$item" "")
        # echo "$item"
    done

    if [[ "$prompt_choose_from_array_multi" == 1 ]];then
        prompt_choose_multi arrayAnswer "${menu[@]}" 
    else
        prompt_choose arrayAnswer "${menu[@]}" 
    fi
}

## prompt_choose convenience function that automatically calls the chosen function
function prompt_choose_function(){
    prompt_choose cmd "$@" \
        && $cmd
}

function prompt_choose_branch(){
    local -n OUTPUT="${1}"

    options=()
    while read line; do
        branch="${line#*\* }"
        txt=""
        if [[ "$branch" != "$line" ]];then
            txt="current"
        fi
        while [[ "$branch" != "${branch# }" ]];do
            branch="${branch# }"
        done
        options+=("$branch" "$branch" "$txt")
    done <<< $(git branch)

    if prompt_choose OUTPUT "${options[@]}";then
        return 0
    fi
    return 1
}